package cn.remex.db;

import cn.remex.core.RemexContext;
import cn.remex.db.exception.RsqlConnectionException;
import cn.remex.db.exception.RsqlExecuteException;
import cn.remex.db.lambdaapi.ColumnPredicate;
import cn.remex.db.lambdaapi.ListColumnPredicate;
import cn.remex.db.lambdaapi.ModelColumnPredicate;
import cn.remex.db.model.SysUser;
import cn.remex.db.rsql.RsqlConstants;
import cn.remex.db.rsql.RsqlConstants.SqlOper;
import cn.remex.db.rsql.RsqlUtils;
import cn.remex.db.rsql.model.Modelable;
import cn.remex.db.rsql.model.SerialNoGenerator;
import cn.remex.db.sql.*;
import cn.remex.db.utils.Assert;
import cn.remex.db.utils.Param;
import cn.remex.db.utils.StringHelper;
import cn.remex.db.utils.exception.ServiceCode;
import cn.remex.db.utils.reflect.ReflectUtil;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.function.Function;

import static cn.remex.db.rsql.RsqlConstants.SYS_id;
import static cn.remex.db.sql.FieldType.TObject;
import static cn.remex.db.utils.Judgment.nullOrBlank;

public class DbCvo<T extends Modelable, ParentType extends Modelable> extends DbCvoBase<T, ParentType> {
    private static final long serialVersionUID = -4526274035605072155L;

    //新版DbCvo Api接口提供Sql操作能力
    public Query<T, ParentType> ready() {
        return new Query<>(this.container,this);
    }
    public DbRvo<T> execute() {
        Query<T, ParentType> query = new Query<>(this.container, this);
        switch (_executeMethod){
            case "Select":
                return query.query();
            case "Update":
                return query.update();
            case "Delete":
                return query.delete();
            case "SQL":
                return query.executeQuery();

            //insert和store处理逻辑稍有差别，大体相同
            case "Insert":
                if(null==this.bean)
                    this.bean = Database.createDbCvo(this.beanClass)._obtainAOPBean();//创建代理bean监控哪些属性变化了,可以用于更新数据库,没有set的字段不用
                this.bean.setId(null);//id为空时将当做新增处理,然后进入store
            case "Store":
                return query.store(this.bean);

            default:
                throw new RsqlExecuteException(ServiceCode.RSQL_EXECUTE_ERROR, "不支持的executeMethod");
        }
    }
    //====filter function======================//
    //filter 开头的函数都是基础当前表的筛选函数，生成where自己的内容。where字句还收到with方法内联对象的filter*方法影响
//    public DbCvo<T, ParentType> filterBy(ColumnPredicate<T> wp, WhereRuleOper oper, Object value) {
//        ReflectUtil.eachFieldWhenGet(_obtainAOPBean(), b -> wp.init((T) b), s -> this.addRule(s, oper, value));
//        return this;
//    }
    public DbCvo<T, ParentType> filterBy(ColumnPredicate<T> wp, WhereRuleOper oper, ColumnPredicate<T> wpValue) {
        rootColumn.withBase(wpValue,c-> ReflectUtil.eachFieldWhenGet(_obtainAOPBean(), b -> wp.init((T) b), s -> this.addRule(s, oper, c)));
        return this;
    }
    public DbCvo<T, ParentType> filterBy(ColumnPredicate<T> wp, WhereRuleOper oper, Object... args) {
        ReflectUtil.eachFieldWhenGet(_obtainAOPBean(), b -> wp.init((T) b), s -> this.getFilter().addRule(s, oper, args));
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> filterBy(ColumnPredicate<T> wp, WhereRuleOper oper, Class<ST> subSelectBeanClass, Consumer<DbCvo<ST, T>> subSelectSqlColumnConsumer){
        DbCvo<ST, T> subSelectDbCvo = new DbCvo<>(_getSpaceName(), subSelectBeanClass, true);
        subSelectDbCvo._setSupDbCvo(this);
        subSelectSqlColumnConsumer.accept(subSelectDbCvo);
        ReflectUtil.eachFieldWhenGet(_obtainAOPBean(), b -> wp.init((T) b), fieldName -> this.filter.addSubSelectRule(fieldName, oper, subSelectDbCvo));
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> filterBy(WhereRuleOper oper, Class<ST> subSelectBeanClass, Consumer<DbCvo<ST, T>> subSelectSqlColumnConsumer){
        DbCvo<ST, T> subSelectDbCvo = new DbCvo<>(_getSpaceName(), subSelectBeanClass, true);
        subSelectDbCvo._setSupDbCvo(this);
        subSelectSqlColumnConsumer.accept(subSelectDbCvo);
        this.filter.addSubSelectRule("_NOT_NEED_FIELD", oper, subSelectDbCvo);
        return this;
    }

    public <ST extends Modelable> DbCvo<T, ParentType> filterByColumn(ColumnPredicate<T> wp, WhereRuleOper oper, Function<DbCvo<T, ParentType>,SqlColumn<?, ?, ?, ?>> valueSqlColumnGenerator){
        SqlColumn<?, ?, ?, ?> valueSqlColumn = valueSqlColumnGenerator.apply(this);
        ReflectUtil.eachFieldWhenGet(_obtainAOPBean(), b -> wp.init((T) b), fieldName -> this.filter.addRule(fieldName, oper, valueSqlColumn));
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> filterBySupColumn(ColumnPredicate<T> wp, WhereRuleOper oper, ColumnPredicate<ParentType> supCp){
        SqlColumn<?, ?, ?, ?> valueSqlColumn = supDbCvo().column(supCp);
        ReflectUtil.eachFieldWhenGet(_obtainAOPBean(), b -> wp.init((T) b), fieldName -> this.filter.addRule(fieldName, oper, valueSqlColumn));
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> filterByModel(ModelColumnPredicate<T, T, ST> mcp, Consumer<SqlColumn<ParentType, T, T, ST>> sqlColumnConsumer){
        rootColumn.withModel(mcp, sqlColumn->{
            //基于DbCvo的filter产生的控制条件将映射到SQL语句中最外层的WHERE子句中；
            //通过以下调换，实现SqlColumn自己的Filter和DbCvo的Filter在顶层Where子句和表连接On子句之间的切换
            sqlColumnConsumer.accept(sqlColumn);//sqlColumn操作的默认在WHere中的dbCvo中
        });
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> filterByList(ListColumnPredicate<T, T, ST> mcp, Consumer<SqlColumn<ParentType, T, T, ST>> sqlColumnConsumer){
        rootColumn.withList(mcp, sqlColumn->{
            //基于DbCvo的filter产生的控制条件将映射到SQL语句中最外层的WHERE子句中；
            //通过以下调换，实现SqlColumn自己的Filter和DbCvo的Filter在顶层Where子句和表连接On子句之间的切换
            sqlColumnConsumer.accept(sqlColumn);//sqlColumn操作的默认在WHere中的dbCvo中
        });
        return this;
    }
    public DbCvo<T, ParentType> filterOper(WhereGroupOp groupOp) {
        this.filter.setGroupOp(groupOp);
        return this;
    }
    public DbCvo<T, ParentType> filterByGroup(Consumer<Where<ParentType, T, T>> groupConsumer) {
        this.filter.setSuperDbCvo(this);
        Where<ParentType, T, T> group = new Where<>();
        group.setSuperDbCvo(this);
        group.setSuperWhere(this.filter);
        this.filter.addGroup(group);

        groupConsumer.accept(group);

        return this;
//        this.filter.setSuperDbCvo(this);
//        Where<T, T> group = new Where<>();
//        group.setSuperDbCvo(this);
//        group.setSuperWhere(this.filter);
//        this.filter.addGroup(group);
//        return group;
    }
    public DbCvo<T, ParentType> filterById(String id) {
        this.rowCount(1);
        this.filterBy(Modelable::getId, WhereRuleOper.equal, id);
        return this;
    }
    public DbCvo<T, ParentType> filter(Where filter){
        this.setFilter(filter);
        return this;
    }
    // guoqianyou 此方法 通过传入model 中的属性值 作为 条件 获取 List 没有解决list，与多级问题
    public DbCvo<T, ParentType> filterByBean(T model) {
        /**
         * guoqianyou
         * 此方法 通过传入model 中的属性值 作为 条件 获取 List
         * 没有解决list，与多级问题
         *
         * LHY 2016-1-17 rename listBy -> filterByBean
         */
        Assert.isTrue(model.getClass().isAssignableFrom(beanClass), ServiceCode.ERROR,  "必须传入查询表对应的Model类型的实例对象。");

        Map<String, Method> baseGetters = SqlType.getGetters(beanClass, FieldType.TBase);
        Map<String, Method> objGetters = SqlType.getGetters(beanClass, TObject);

        for (String fieldName : baseGetters.keySet()) {
            Object value = ReflectUtil.invokeGetter(fieldName, model);
            if (nullOrBlank(value) || value.equals(0))
                continue;
            this.addRule(fieldName, WhereRuleOper.equal, String.valueOf(value));
        }

        for (String fieldName : objGetters.keySet()) {
            Object value = ReflectUtil.invokeGetter(fieldName, model);
            if (nullOrBlank(value) || value.equals(0))
                continue;
            this.addRule(fieldName, WhereRuleOper.equal, String.valueOf(ReflectUtil.invokeGetter("id", value)));
        }

        return this;
    }

    //====order======================//
    //order 开头的函数都是排序函数
    public DbCvo<T, ParentType> orderBy(Object sidx, String sord) {
        this.addOrder(true, sidx, sord);
        return this;
    }
    public DbCvo<T, ParentType> orderBy(ColumnPredicate<T> cp, Sort s) {
        rootColumn.withBase(cp,column->this.addOrder(true, column, s.toString()));
        return this;
    }

    //====group======================//
    //====update 操作======================//

    //====page control======================//
    //分页函数
    public DbCvo<T, ParentType> page(int page){
        setPagination(page);
        return this;
    }
    public DbCvo<T, ParentType> rowCount(int rowCount){
        setRowCount(rowCount);
        return this;
    }

    //====With ======================//
    //with 开头的方法均控制语句的输出字段或更新字段
    public DbCvo<T, ParentType> withColumn(String... fields) {
        for (String field : fields) {
            rootColumn.withColumn(field);
        }
        return this;
    }
    public DbCvo<T, ParentType> withBase(ColumnPredicate<T> cp, Consumer<SqlColumn<ParentType, T, T, ?>> sqlColumnConsumer) {
        rootColumn.withBase(cp, sqlColumnConsumer);
        return this;
    }
    public DbCvo<T, ParentType> withBase() {
        rootColumn.withBase();
        return this;
    }
    public DbCvo<T, ParentType> withBase(ColumnPredicate<T> cp) {
        rootColumn.withBase(cp);
        return this;
    }
    public DbCvo<T, ParentType> withBase(String fieldName, Consumer<SqlColumn<ParentType, T, T, ?>> sqlColumnConsumer) {
        rootColumn.withBase(fieldName,sqlColumnConsumer);
        return this;
    }
    public DbCvo<T, ParentType> withBase(String fieldName) {
        rootColumn.withBase(fieldName);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withModel(ModelColumnPredicate<T, T, ST> mcp, Consumer<SqlColumn<ParentType, T, T, ST>> sqlColumnConsumer) {
        rootColumn.withModel(mcp, sqlColumnConsumer);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withModel(ModelColumnPredicate<T, T, ST> mcp) {
        rootColumn.withModel(mcp);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withModel(String fieldName, Consumer<SqlColumn<ParentType, T, T, ST>> sqlColumnConsumer) {
        rootColumn.withModel(fieldName,sqlColumnConsumer);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withModel(String fieldName) {
        rootColumn.withModel(fieldName);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withList(ListColumnPredicate<T, T, ST> mcp, Consumer<SqlColumn<ParentType, T, T, ST>> sqlColumnConsumer) {
        rowCount(100000);
        rootColumn.withList(mcp, sqlColumnConsumer);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withList(ListColumnPredicate<T, T, ST> mcp) {
        rowCount(100000);
        rootColumn.withList(mcp);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withList(String fieldName, Consumer<SqlColumn<ParentType, T, T, ST>> sqlColumnConsumer) {
        rowCount(100000);
        rootColumn.withList(fieldName, sqlColumnConsumer);
        return this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> withList(String fieldName) {
        rowCount(100000);
        rootColumn.withList(fieldName);
        return this;
    }

    //====assign ======================//
    //assign 开头的方法均用于更新或新增数据时为列指定值
    public DbCvo<T, ParentType> assignColumn(ColumnPredicate<T> cp, Object o) {
        rootColumn.withBase(cp,base-> this.$S(base.getFieldName(), o instanceof Modelable ? ((Modelable) o).getId(): o));
        return  this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> assignColumn(String fieldName, Object o) {
        rootColumn.withBase(fieldName,base-> this.$S(base.getFieldName(), o instanceof Modelable ? ((Modelable) o).getId(): o));
        return  this;
    }
    public DbCvo<T, ParentType> assignIgnoreNull(ColumnPredicate<T> cp, Object o) {
        if (null != o) {
            rootColumn.withBase(cp, base -> this.$S(base.getFieldName(), o instanceof Modelable ? ((Modelable) o).getId() : o));
        }
        return  this;
    }
    public DbCvo<T, ParentType> assignIgnoreBlank(ColumnPredicate<T> cp, Object o) {
        if (!nullOrBlank(o)) {
            rootColumn.withBase(cp, base -> this.$S(base.getFieldName(), o instanceof Modelable ? ((Modelable) o).getId() : o));
        }
        return  this;
    }
    public DbCvo<T, ParentType> assignNull(ColumnPredicate<T> cp) {
        rootColumn.withBase(cp, base -> this.$S(base.getFieldName(), null));
        return  this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> assignColumn(ColumnPredicate<T> cp, Class<ST> subSelectBeanClass, Consumer<DbCvo<ST, T>> subSelectSqlColumnConsumer) {
        DbCvo<ST, T> subDbCvo = new DbCvo<>(_getSpaceName(), subSelectBeanClass, true);
        subDbCvo._setSupDbCvo(this);
        subSelectSqlColumnConsumer.accept(subDbCvo);
        rootColumn.withBase(cp,base-> base.setSubDbCvo(subDbCvo));
        return  this;
    }
    public <ST extends Modelable> DbCvo<T, ParentType> assignColumn(ColumnPredicate<T> cp, DbCvo<ST, T> subDbCvo) {
        subDbCvo._setSpaceName(_getSpaceName());
        rootColumn.withBase(cp,base-> base.setSubDbCvo(subDbCvo));
        return  this;
    }
    public DbCvo<T, ParentType> assignBean(T dbBean) {
        this.bean = dbBean;
        if (!dbBean.modelIsNew())
            this.filterById(dbBean.getId());
//        this.withBase();
        SqlType.getFields(this.getBeanClass(),FieldType.TAll).forEach((fieldName,fieldType)->{
            Object o = ReflectUtil.invokeGetter(fieldName,this.bean);
            if (o != null) {
                this.withColumn(fieldName);
                this.$S(fieldName, o instanceof Modelable ? ((Modelable) o).getId(): o);
            }
        });
        return this;
    }


    //====统计功能 ======================//
    public DbCvo<T, ParentType> groupBy(ColumnPredicate<T> cp) {
        return this.groupBy(cp,null,null);
    }
    public DbCvo<T, ParentType> groupBy(ColumnPredicate<T> cp, String groupAlias) {
        return this.groupBy(cp,groupAlias,null);
    }
    public DbCvo<T, ParentType> groupBy(ColumnPredicate<T> cp, String groupAlias, GroupFunction gf,String... funArgs) {
        this.withBase(cp, sc->{
            if(nullOrBlank(gf)){
                sc.groupBy();
            }else{
                sc.groupBy(gf,funArgs);
            }
            if(!nullOrBlank(groupAlias)){
                sc.groupAlias(groupAlias);
            }
        });
        return this;
    }
    public DbCvo<T, ParentType> aggregateBy(ColumnPredicate<T> cp, AggregateFunction af) {
        return this.aggregateBy(cp, af, null);
    }
    public DbCvo<T, ParentType> aggregateBy(ColumnPredicate<T> cp, AggregateFunction af, String aggregateAlias,String... funArgs) {
        this.withBase(cp, sc->{
            sc.aggregateBy(af,funArgs);
            if(!nullOrBlank(aggregateAlias)){
                sc.aggregateAlias(aggregateAlias);
            }
        });
        return this;
    }



    //====function for 列操作======================//
    //为前端准备的方法，通过字符串添加属性列.字符串表达式支持链式访问包括 . [] :  通过分号可以一次添加多个
    public static final String regx = "([A-Za-z_\\*][A-Za-z\\d_,]*)$|(([A-Za-z_][A-Za-z\\d_]*)\\.)|(([A-Za-z_][A-Za-z\\d_]*)\\[\\]\\.)";
    public DbCvo<T, ParentType> withExprColumns(String columnExprs) {
        boolean[] end = {false};
        Param param = new Param(null);
        for (String expr : columnExprs.split(";")) {
            end[0] = false;
            param.param = null;
            StringHelper.forEachMatch(expr, regx, (m, b) -> {
                String baseField = m.group(1), objField = m.group(3), listField = m.group(5);
                if (baseField != null) {
                    for (String field : baseField.split(",")) {
                        if("*".equals(field)){
                            ReflectUtil.invokeMethod("withBase",param.param == null?this: param.param);
                        }else {
                            ReflectUtil.invokeMethod("withBase",param.param == null?this: param.param, field);
                        }
                    }
                } else if (objField != null) {
                    if (param.param == null) {
                       this.withModel(objField, curModel -> param.param = curModel);
                    } else
                        ((SqlColumn) param.param).withModel(objField, curModel -> param.param = curModel);
                } else if (listField != null){
                    if (param.param == null) {
                        this.withList(listField, curList -> param.param = curList);
                    } else
                        ((SqlColumn) param.param).withList(listField, curList -> param.param = curList);
                }
                end[0] = b;
            });

            Assert.isTrue(end[0],  ServiceCode.ERROR, "表达式不合法，只允许name.   name[].  name 三种格式!");
        }

        return this;
    }
    public SqlColumn<?,?,?,?> column(ColumnPredicate<T> cp) {
        Param<SqlColumn<ParentType, T, T, ?>> param = new Param<>();
        Consumer<SqlColumn<ParentType, T, T, ?>> sqlColumnConsumer = sqlColumn->{
            sqlColumn._setNotWith(true);//使用不用查询出来 TODO 如果既要查出来,同时又要给子查询当查询条件,则可能出问题.
            param.param = sqlColumn;
        };
        rootColumn.withBase(cp, sqlColumnConsumer);
        return param.param;
    }
    //将要废弃的方法 此方法被withColumn方法替代.如果是前端传过来的参数结构调整为
    @Deprecated
    public DbCvo<T, ParentType> putExtColumn(final String extColumns) {
        for (String extColumn : extColumns.split(";")) {
            String[] columns = extColumn.split("\\.");
            Assert.isTrue(columns.length <= 3, ServiceCode.ERROR,  "putExtColumn方法只能支持两层属性拓展");

//            SqlColumn<T, T, ST> sc = new SqlColumn<>(this, null);
//            Class<ST> nodeClass = (Class<ST>) SqlType.getFields(beanClass, SqlType.FieldType.TObject).get(columns[0].toString());
//            ST nodeBean = ReflectUtil.createAopBean(nodeClass);
//            sc._init(columns[0], nodeBean, nodeClass, nodeClass, SqlType.FieldType.TObject);
//            this.addColumn(sc);//添加到DbCvo中将来dataCloumns属性将不再使用

            if(columns.length==1){
                rootColumn.withBase(columns[0]);
            }else{
                rootColumn.withModel(columns[0], m -> {
                    if(columns[1].indexOf("[")>0){
                        m.withList(columns[1],m2->{
                            m2.withBase(columns[2]);
                        });
                    }else if(columns.length>2){
                        m.withModel(columns[1],m2->{
                            m2.withBase(columns[2]);
                        });
                    }else{
                        m.withBase(columns[1]);
                    }

                });
            }

        }
        return this;
    }

    //====function for stream/内循环 TODO ======================//
    //内循环
    public DbCvo<T, ParentType> eachRow(Consumer<List> rowConsumer) {
        this.rowConsumer = rowConsumer;
        return this;
    }

    //====function for 嵌套查询 ======================//
    public DbCvo<ParentType, ?> supDbCvo() {
        Assert.notNullAndEmpty(_supDbCvo, ServiceCode.RSQL_ERROR, "子查询之前,必须初始化上一级的查询");
        return _supDbCvo;
    }



    //====core method======================//
    // 原来写好的方法，很核心，有优化，基本不用大动
    public DbCvo(String spaceName, Class<T> beanClass) {
        _init(spaceName, beanClass);
    }
    public DbCvo(String spaceName, Class<T> beanClass, boolean _isSubStatment) {
        this._isSubStatment = _isSubStatment;
        _init(spaceName, beanClass);
    }
    public DbCvo(String spaceName, Class<T> beanClass, Map<String, Object> params) {
        if (null != params)
            putParameters(params);

        _init(spaceName, beanClass);
    }
    public DbCvo(String spaceName, Class<T> beanClass, SqlOper oper) {
        Assert.notNull(oper, ServiceCode.ERROR,  "数据库操作符oper不能为空！");
        this.oper = oper;
        _init(spaceName, beanClass);
    }
//    public DbCvo(String spaceName, Class<T> beanClass, SqlOper oper/*, String dataType, 2016-8-21 LHY 删除dataType*/) {
//        Assert.notNull(oper, ServiceCode.ERROR,  "数据库操作符oper不能为空！");
//        this.oper = oper;
//        if (null != dataType) this.dataType = dataType;
//        _init(spaceName, beanClass);
//    }
    public DbCvo(String spaceName, Class<T> beanClass, SqlOper oper, /*String dataType, 2016-8-21 LHY 删除dataType*/SqlColumn rootColumn) {
        Assert.notNull(oper, ServiceCode.ERROR,  "数据库操作符oper不能为空！");
        this.oper = oper;
        //if (null != dataType) this.dataType = dataType;
        if (null != rootColumn) this.rootColumn = rootColumn;
        _init(spaceName, beanClass);
    }
    // 此构造用于执行sql语句，如果需要参数，则sqlString中可以用:paramName。 相对应params中的key必须为相应的paramName
    public DbCvo(String spaceName, final String sqlString, final Map<String, Object> params) {
        this.sqlString = sqlString;
        this.oper = SqlOper.sql;
        if (null != params)
            putParameters(params);
        _init(spaceName, null);
    }
    // 此构造用于执行sql语句，如果需要参数，则sqlString中可以用:paramName。 相对应params中的key必须为相应的paramName
    public DbCvo(String spaceName, final String sqlString, final SqlOper oper, final Map<String, Object> params) {
        this.sqlString = sqlString;
        this.oper = oper;
        if (null != params)
            putParameters(params);
        _init(spaceName, null);
    }

    //====内部方法 method======================//
    // init方法仅且必须被所有DbCvo的构造函数调用.
    private void _init(String spaceName, final Class<T> clazz) {
        Class<T> clazz1=clazz;
        if(null != clazz1){
            try {
                clazz1 = (Class<T>) Class.forName(StringHelper.getClassName(clazz1));
            } catch (ClassNotFoundException e) {
                throw new RsqlConnectionException(ServiceCode.RSQL_BEANCLASS_ERROR, "初始化DbCvo时,beanClass异常！", e);
            }
            this.beanName = StringHelper.getClassSimpleName(clazz1);
        }else{
            this.beanName = "sqlString_" + sqlString.hashCode();
            this._sqlString = this._prettySqlString = this._litterSqlString = this.sqlString; //直接传的sql 不用生成内部执行的sql
        }

        this.beanClass = clazz1;

        this.spaceName = spaceName;

        if(null!=beanClass && null == this.rootColumn)this.rootColumn  = new SqlColumn(this,beanClass, _obtainAOPBean());

    }
    public void _initForRsqlDao() {
        if (SqlOper.list.equals(oper) || SqlOper.view.equals(oper)) {
            RsqlUtils.createSelectSql(this);
        } else if (SqlOper.add.equals(oper)) {
            RsqlUtils.createInsertSql(this);
        } else if (SqlOper.edit.equals(oper)) {
            RsqlUtils.createUpdateSql(this);
        } else if (SqlOper.del.equals(oper)) {
            RsqlUtils.createDeleteSql(this);
        } else if (SqlOper.sql.equals(oper)) {
            RsqlUtils.createStringSql(this);
        } else {
            throw new RsqlExecuteException(ServiceCode.RSQL_ERROR, "oper 操作指令错误！");
        }

        if(SqlOper.edit.equals(oper) || SqlOper.add.equals(oper)){
            // 只有在添加的时候修改者三个字段
            Date now = new Date((System.currentTimeMillis()/1000)*1000);
            SysUser au = RemexContext.obtainCurUser();
            String un = au == null || nullOrBlank(au.getUsername()) ? "NONE" : au.getUsername();
            if (oper == SqlOper.add) {
                $S(RsqlConstants.SYS_createTime, now);
                $S(RsqlConstants.SYS_createOperator, un);
                $S(RsqlConstants.SYS_ownership, un);
            }
            $S(RsqlConstants.SYS_modifyTime, now);
            $S(RsqlConstants.SYS_modifyOperator, un);
        }

        _initSqlString(_sqlString);

        Where<ParentType, T, T> curWhere = this.getFilter();
        if (curWhere.isFilter()) {
            for (WhereRule rule : curWhere.getAllRules()) {
                this.$S(rule.getParamName(), rule.getData());
            }
        } else if (!nullOrBlank(curWhere.getSearchField())) {
            this.$S(curWhere.getSearchField(), curWhere.getSearchString());
        }
        //onFilete和whereFilter 分开后，需要将数据填到DBCVO中。
        if(null!=_getRootColumn())
            _getRootColumn().forEvery(sqlColumn -> {
                if(null!=sqlColumn.getOnFilter()){
                    List<WhereRule> curAllRules = sqlColumn.getOnFilter().getAllRules();
                    for (WhereRule rule : curAllRules) {
                        this.$S(rule.getParamName(), rule.getData());
                    }
                }
            });

        if(null!=this._getRootColumn())this._getRootColumn().forEvery(c1 -> {
            if (null != c1.getFilter())
                ((List<WhereRule>) c1.getFilter().getAllRules()).forEach(rule -> this.$S(rule.getParamName(), rule.getData()));
        });


        // 初始化sql语句中需要的命名参数
        for (NamedParam namedParam : this._getNamedParams()) {
            String key = namedParam.getName();
            if (this.containsKey(key)) {
                Object paramValue = this.$V(key);
                namedParam.setValue(paramValue);
            }
        }

        // insert 语句添加自动主键
        if (null != this.getBean()
                && this._sqlString.substring(0, 6).equalsIgnoreCase("INSERT")) {
            SerialNoGenerator idgen = ((SerialNoGenerator) this.getBean());//2016-10-01 允许手动指定主键
            String id = idgen.obtainNewId()!=null?idgen.obtainNewId():idgen.generateId();
            // this.$S(SYS_id, id);
            this.getBean().setId(id);
            this.setId(id);
            this._namedParams.stream().filter(np-> SYS_id.equals(np.getName())).findFirst().ifPresent(np->np.setValue(id));
        }
    }
    public void _initForSubStatement(DbCvoBase<?,?> dbCvo,  Param<Integer> tableIndex, Param<Integer> paramIndex){
        _setParamIndex(paramIndex);
        _setTableAliasName("SS" + (tableIndex.param++));
        _setNamedParams(dbCvo._getNamedParams());
        _initForRsqlDao();
        getParameters().forEach((k, v) -> dbCvo.$S(k, v));
    }
    private void _initSqlString(final String sqlString) {
        // 初始化sqlString
        // 排序必须放在这里没有办法
        this._prettySqlString = sqlString;
        this._sqlString = this._prettySqlString.replaceAll("\\s+", " ");
        this._litterSqlString = this._sqlString.length() > 20 ? this._sqlString
                .substring(0, 20) + "..." : this._sqlString;

        // 先初始化参数名称和类型
//        if (null != namedParams) {
//            for (NamedParam param : namedParams) {
//                NamedParam paramNew = new NamedParam(-1, param.getName(), param.getType(), null);
//                this._namedParams.add(paramNew);
//            }
//        }
        // 在初始化参数的序号
        TreeMap<Integer, String> paramIndexs = RsqlUtils.obtainNamedParamIndexs(this._sqlString);
        for (NamedParam param : this._namedParams) {
            Integer okIdx = null;
            for(Integer idx:paramIndexs.keySet()){
                if(param.getName().equals(paramIndexs.get(idx))){
                    okIdx = idx;
                    break;
                }
            }
            if(null!=okIdx){
                paramIndexs.remove(okIdx);
                param.setIndex(okIdx);
            }
        }

        // 调用RsqlAcessEngine将sql转化为通过验证数据权限的sql
        this._sqlString = RsqlUtils.obtainNamedSql(this._sqlString);
    }
    public DbCvo<T, ParentType> executeMethod(String executeMethod) {
        _executeMethod = executeMethod;
        return this;
    }
    //====getter and setter======================//

}
